
package server.quest;


import client.MapleCharacter;
import client.MapleQuestStatus;
import client.MapleStat;
import client.MapleTraitType;
import client.inventory.InventoryException;
import client.inventory.MapleInventoryType;
import client.skills.Skill;
import client.skills.SkillEntry;
import client.skills.SkillFactory;
import constants.GameConstants;
import constants.ItemConstants;
import constants.JobConstants;
import server.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import server.RandomRewards;
import tools.*;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
























 public class MapleQuestAction implements Serializable {
       private static final long serialVersionUID = 9179541993413738569L;
       private final MapleQuestActionType type;
       private final MapleQuest quest;
       private final List<Integer> applicableJobs;



    public MapleQuestAction(MapleQuestActionType type, ResultSet rse, MapleQuest quest, PreparedStatement pss, PreparedStatement psq, PreparedStatement psi) throws SQLException {

        ResultSet rs;
        /*  34 */
        this.applicableJobs = new ArrayList<>();
        /*  35 */
        this.intStore = 0;
        /*  36 */
        this.items = null;
        /*  37 */
        this.skill = null;
        /*  38 */
        this.state = null;





        /*  44 */
        this.type = type;
        /*  45 */
        this.quest = quest;

        /*  47 */
        this.intStore = rse.getInt("intStore");
        /*  48 */
        String[] jobs = rse.getString("applicableJobs").split(", ");
        /*  49 */
        if (jobs.length <= 0 && rse.getString("applicableJobs").length() > 0) {
            /*  50 */
            this.applicableJobs.add(Integer.valueOf(Integer.parseInt(rse.getString("applicableJobs"))));

        }
        /*  52 */
        for (String j : jobs) {
            /*  53 */
            if (j.length() > 0) {
                /*  54 */
                this.applicableJobs.add(Integer.valueOf(Integer.parseInt(j)));

            }

        }

        switch (type) {
            case item:
                items = new ArrayList<>();
                psi.setInt(1, rse.getInt("uniqueid"));
                rs = psi.executeQuery();
                while (rs.next()) {
                    items.add(new QuestItem(rs.getInt("itemid"), rs.getInt("count"), rs.getInt("period"), rs.getInt("gender"), rs.getInt("job"), rs.getInt("jobEx"), rs.getInt("prop")));
                }
                rs.close();
                break;
            case quest:
                state = new ArrayList<>();
                psq.setInt(1, rse.getInt("uniqueid"));
                rs = psq.executeQuery();
                while (rs.next()) {
                    state.add(new Pair<>(rs.getInt("quest"), rs.getInt("state")));
                }
                rs.close();
                break;
            case skill:
                skill = new ArrayList<>();
                pss.setInt(1, rse.getInt("uniqueid"));
                rs = pss.executeQuery();
                while (rs.next()) {
                    skill.add(new Triple<>(rs.getInt("skillid"), rs.getInt("skillLevel"), rs.getInt("masterLevel")));
                }
                rs.close();
                break;
        }

    }

       private int intStore;
    private List<QuestItem> items;
    private List<Triple<Integer, Integer, Integer>> skill;
    private List<Pair<Integer, Integer>> state;


    private static boolean canGetItem(QuestItem item, MapleCharacter chr) {
        /*  90 */
        if (item.gender != 2 && item.gender >= 0 && item.gender != chr.getGender()) {
            /*  91 */
            return false;

        }
        /*  93 */
        if (item.job > 0) {
            /*  94 */
            List<Integer> code = getJobBy5ByteEncoding(item.job);
            /*  95 */
            boolean jobFound = false;
            /*  96 */
            for (Iterator<Integer> iterator = code.iterator(); iterator.hasNext(); ) {
                int codec = ((Integer) iterator.next()).intValue();
                /*  97 */
                if (codec / 100 == chr.getJob() / 100) {
                    /*  98 */
                    jobFound = true;

                    break;

                }
            }

            /* 102 */
            if (!jobFound && item.jobEx > 0) {
                /* 103 */
                List<Integer> codeEx = getJobBySimpleEncoding(item.jobEx);
                /* 104 */
                for (Iterator<Integer> iterator1 = codeEx.iterator(); iterator1.hasNext(); ) {
                    int codec = ((Integer) iterator1.next()).intValue();
                    /* 105 */
                    if (codec / 100 % 10 == chr.getJob() / 100 % 10) {
                        /* 106 */
                        jobFound = true;

                        break;

                    }
                }


            }
            /* 111 */
            return jobFound;

        }
        /* 113 */
        return true;

    }



    private static List<Integer> getJobBy5ByteEncoding(int encoded) {
        /* 117 */
        List<Integer> ret = new ArrayList<>();
        /* 118 */
        if ((encoded & 0x1) != 0) {
            /* 119 */
            ret.add(Integer.valueOf(0));

        }
        /* 121 */
        if ((encoded & 0x2) != 0) {
            /* 122 */
            ret.add(Integer.valueOf(100));

        }
        /* 124 */
        if ((encoded & 0x4) != 0) {
            /* 125 */
            ret.add(Integer.valueOf(200));

        }
        /* 127 */
        if ((encoded & 0x8) != 0) {
            /* 128 */
            ret.add(Integer.valueOf(300));

        }
        /* 130 */
        if ((encoded & 0x10) != 0) {
            /* 131 */
            ret.add(Integer.valueOf(400));

        }
        /* 133 */
        if ((encoded & 0x20) != 0) {
            /* 134 */
            ret.add(Integer.valueOf(500));

        }
        /* 136 */
        if ((encoded & 0x400) != 0) {
            /* 137 */
            ret.add(Integer.valueOf(1000));

        }
        /* 139 */
        if ((encoded & 0x800) != 0) {
            /* 140 */
            ret.add(Integer.valueOf(1100));

        }
        /* 142 */
        if ((encoded & 0x1000) != 0) {
            /* 143 */
            ret.add(Integer.valueOf(1200));

        }
        /* 145 */
        if ((encoded & 0x2000) != 0) {
            /* 146 */
            ret.add(Integer.valueOf(1300));

        }
        /* 148 */
        if ((encoded & 0x4000) != 0) {
            /* 149 */
            ret.add(Integer.valueOf(1400));

        }
        /* 151 */
        if ((encoded & 0x8000) != 0) {
            /* 152 */
            ret.add(Integer.valueOf(1500));

        }
        /* 154 */
        if ((encoded & 0x20000) != 0) {
            /* 155 */
            ret.add(Integer.valueOf(2001));
            /* 156 */
            ret.add(Integer.valueOf(2200));

        }
        /* 158 */
        if ((encoded & 0x100000) != 0) {
            /* 159 */
            ret.add(Integer.valueOf(2000));
            /* 160 */
            ret.add(Integer.valueOf(2001));

        }
        /* 162 */
        if ((encoded & 0x200000) != 0) {
            /* 163 */
            ret.add(Integer.valueOf(2100));

        }
        /* 165 */
        if ((encoded & 0x400000) != 0) {
            /* 166 */
            ret.add(Integer.valueOf(2001));
            /* 167 */
            ret.add(Integer.valueOf(2200));

        }
        /* 169 */
        if ((encoded & 0x40000000) != 0) {
            /* 170 */
            ret.add(Integer.valueOf(3000));
            /* 171 */
            ret.add(Integer.valueOf(3200));
            /* 172 */
            ret.add(Integer.valueOf(3300));
            /* 173 */
            ret.add(Integer.valueOf(3500));

        }
        /* 175 */
        return ret;

    }



    private static List<Integer> getJobBySimpleEncoding(int encoded) {
        /* 179 */
        List<Integer> ret = new ArrayList<>();
        /* 180 */
        if ((encoded & 0x1) != 0) {
            /* 181 */
            ret.add(Integer.valueOf(200));

        }
        /* 183 */
        if ((encoded & 0x2) != 0) {
            /* 184 */
            ret.add(Integer.valueOf(300));

        }
        /* 186 */
        if ((encoded & 0x4) != 0) {
            /* 187 */
            ret.add(Integer.valueOf(400));

        }
        /* 189 */
        if ((encoded & 0x8) != 0) {
            /* 190 */
            ret.add(Integer.valueOf(500));

        }
        /* 192 */
        return ret;

    }



    public boolean RestoreLostItem(MapleCharacter chr, int itemid) {
        /* 196 */
        if (this.type == MapleQuestActionType.item) {
            /* 197 */
            for (QuestItem item : this.items) {
                /* 198 */
                if (item.itemid == itemid) {
                    /* 199 */
                    if (!chr.haveItem(item.itemid, item.count, true, false)) {
                        /* 200 */
                        MapleInventoryManipulator.addById(chr.getClient(), item.itemid, (short) item.count, "Obtained from quest (Restored) " + this.quest.getId() + " on " + DateUtil.getCurrentDate());

                    }
                    /* 202 */
                    return true;

                }

            }

        }
        /* 206 */
        return false;
    }

    public void runStart(MapleCharacter chr, Integer extSelection) {
        MapleQuestStatus status;

        /* 214 */
        switch (type) {
            case exp:
                status = chr.getQuest(quest);
                if (status.getForfeited() > 0) {
                    break;
                }
                chr.gainExp(intStore * GameConstants.getExpRate_Quest(chr.getLevel()) * (chr.getStat().questBonus) * ((chr.getTrait(MapleTraitType.sense).getLevel() * 3 / 10) + 100) / 100, true, true, true);
                break;
            case item:
                // first check for randomness in item selection
                Map<Integer, Integer> props = new HashMap<>();
                for (QuestItem item : items) {
                    if (item.prop > 0 && canGetItem(item, chr)) {
                        for (int i = 0; i < item.prop; i++) {
                            props.put(props.size(), item.itemid);
                        }
                    }
                }
                int selection = 0;
                int extNum = 0;
                if (props.size() > 0) {
                    selection = props.get(Randomizer.nextInt(props.size()));
                }
                for (QuestItem item : items) {
                    if (!canGetItem(item, chr)) {
                        continue;
                    }
                    int id = item.itemid;
                    if (item.prop != -2) {
                        if (item.prop == -1) {
                            if (extSelection != null && extSelection != extNum++) {
                                continue;
                            }
                        } else if (id != selection) {
                            continue;
                        }
                    }
                    short count = (short) item.count;
                    if (count < 0) { // 删除任务道具
                        try {
                            MapleInventoryManipulator.removeById(chr.getClient(), ItemConstants.getInventoryType(id), id, (count * -1), true, false);
                        } catch (InventoryException ie) {
                            // it's better to catch this here so we'll atleast try to remove the other items
                            System.err.println("[h4x] Completing a quest without meeting the requirements" + ie);
                        }
                        chr.send(MaplePacketCreator.getShowItemGain(id, count, true));
                    } else { // 给任务奖励道具
                        int period = item.period / 1440; //转换成天
                        String name = MapleItemInformationProvider.getInstance().getName(id);
                        if (id / 10000 == 114 && name != null && name.length() > 0) { //如果是勋章道具
                            String msg = "恭喜您获得勋章 <" + name + ">";
                            chr.dropMessage(-1, msg);
                            chr.dropMessage(5, msg);
                        }
                        MapleInventoryManipulator.addById(chr.getClient(), id, count, "", null, period, "任务获得 " + quest.getId() + " 时间: " + DateUtil.getCurrentDate());
                        chr.send(MaplePacketCreator.getShowItemGain(id, count, true));
                    }
                }
                break;
            case nextQuest:
                status = chr.getQuest(quest);
                if (status.getForfeited() > 0) {
                    break;
                }
                chr.send(MaplePacketCreator.updateQuestInfo(quest.getId(), status.getNpc(), intStore, false));
                break;
            case money:
                status = chr.getQuest(quest);
                if (status.getForfeited() > 0) {
                    break;
                }
                chr.gainMeso(intStore, true, true);
                break;
            case quest:
                for (Pair<Integer, Integer> q : state) {
                    chr.updateQuest(new MapleQuestStatus(MapleQuest.getInstance(q.left), q.right));
                }
                break;
            case skill:
                Map<Integer, SkillEntry> list = new HashMap<>();
                for (Triple<Integer, Integer, Integer> skills : skill) {
                    int skillid = skills.left;
                    int skillLevel = skills.mid;
                    int masterLevel = skills.right;
                    Skill skillObject = SkillFactory.getSkill(skillid);
                    boolean found = false;
                    for (int applicableJob : applicableJobs) {
                        if (chr.getJob() == applicableJob) {
                            found = true;
                            break;
                        }
                    }
                    if (skillObject.isBeginnerSkill() || found) {
                        list.put(skillid, new SkillEntry((byte) Math.max(skillLevel, chr.getSkillLevel(skillObject)), (byte) Math.max(masterLevel, chr.getMasterLevel(skillObject)), SkillFactory.getDefaultSExpiry(skillObject)));
                    }
                }
                chr.changeSkillsLevel(list);
                break;
            case pop:
                status = chr.getQuest(quest);
                if (status.getForfeited() > 0) {
                    break;
                }
                int fameGain = intStore;
                chr.addFame(fameGain);
                chr.updateSingleStat(MapleStat.人气, chr.getFame());
                chr.send(MaplePacketCreator.getShowFameGain(fameGain));
                break;
            case buffItemID:
                status = chr.getQuest(quest);
                if (status.getForfeited() > 0) {
                    break;
                }
                int tobuff = intStore;
                if (tobuff <= 0) {
                    break;
                }
                MapleItemInformationProvider.getInstance().getItemEffect(tobuff).applyTo(chr);
                break;
            case infoNumber: {
//		System.out.println("quest : "+intStore+"");
//		MapleQuest.getInstance(intStore).forceComplete(c, 0);
                break;
            }
            case sp: {
                status = chr.getQuest(quest);
                if (status.getForfeited() > 0) {
                    break;
                }
                int sp_val = intStore;
                if (applicableJobs.size() > 0) {
                    int finalJob = 0;
                    for (int job_val : applicableJobs) {
                        if (chr.getJob() >= job_val && job_val > finalJob) {
                            finalJob = job_val;
                        }
                    }
                    if (finalJob == 0) {
                        chr.gainSP(sp_val);
                    } else {
                        chr.gainSP(sp_val, JobConstants.getSkillBookByJob(finalJob));
                    }
                } else {
                    chr.gainSP(sp_val);
                }
                break;
            }
            case charmEXP:
            case charismaEXP:
            case craftEXP:
            case insightEXP:
            case senseEXP:
            case willEXP: {
                status = chr.getQuest(quest);
                if (status.getForfeited() > 0) {
                    break;
                }
                chr.getTrait(MapleTraitType.getByQuestName(type.name())).addExp(intStore, chr);
                break;
            }
            default:
                break;
        }
    }


    public boolean checkEnd(MapleCharacter chr, Integer extSelection) {
        switch (type) {
            case item: {
                // first check for randomness in item selection
                Map<Integer, Integer> props = new HashMap<>();

                for (QuestItem item : items) {
                    if (item.prop > 0 && canGetItem(item, chr)) {
                        for (int i = 0; i < item.prop; i++) {
                            props.put(props.size(), item.itemid);
                        }
                    }
                }
                int selection = 0;
                int extNum = 0;
                if (props.size() > 0) {
                    selection = props.get(Randomizer.nextInt(props.size()));
                }
                byte eq = 0, use = 0, setup = 0, etc = 0, cash = 0;

                for (QuestItem item : items) {
                    if (!canGetItem(item, chr)) {
                        continue;
                    }
                    int id = item.itemid;
                    if (item.prop != -2) {
                        if (item.prop == -1) {
                            if (extSelection != null && extSelection != extNum++) {
                                continue;
                            }
                        } else if (id != selection) {
                            continue;
                        }
                    }
                    short count = (short) item.count;
                    if (count < 0) { // 删除任务道具检测
                        if (!chr.haveItem(id, count, false, true)) {
                            chr.dropMessage(1, "您的任务道具不够，还不能完成任务.");
                            return false;
                        }
                    } else { // 给角色任务奖励检测
                        if (MapleItemInformationProvider.getInstance().isPickupRestricted(id) && chr.haveItem(id, 1, true, false)) {
                            chr.dropMessage(1, "You have this item already: " + MapleItemInformationProvider.getInstance().getName(id));
                            return false;
                        }
                        switch (ItemConstants.getInventoryType(id)) {
                            case EQUIP:
                                eq++;
                                break;
                            case USE:
                                use++;
                                break;
                            case SETUP:
                                setup++;
                                break;
                            case ETC:
                                etc++;
                                break;
                            case CASH:
                                cash++;
                                break;
                        }
                    }
                }
                if (chr.getInventory(MapleInventoryType.EQUIP).getNumFreeSlot() < eq) {
                    chr.dropMessage(1, "装备栏空间不足.");
                    return false;
                } else if (chr.getInventory(MapleInventoryType.USE).getNumFreeSlot() < use) {
                    chr.dropMessage(1, "消耗栏空间不足.");
                    return false;
                } else if (chr.getInventory(MapleInventoryType.SETUP).getNumFreeSlot() < setup) {
                    chr.dropMessage(1, "设置栏空间不足.");
                    return false;
                } else if (chr.getInventory(MapleInventoryType.ETC).getNumFreeSlot() < etc) {
                    chr.dropMessage(1, "其他栏空间不足.");
                    return false;
                } else if (chr.getInventory(MapleInventoryType.CASH).getNumFreeSlot() < cash) {
                    chr.dropMessage(1, "特殊栏空间不足.");
                    return false;
                }
                return true;
            }
            case money: {
                int meso = intStore;
                if (chr.getMeso() + meso < 0) { // Giving, overflow
                    chr.dropMessage(1, "携带金币数量已达限制.");
                    return false;
                } else if (meso < 0 && chr.getMeso() < Math.abs(meso)) { //remove meso
                    chr.dropMessage(1, "金币不足.");
                    return false;
                }
                return true;
            }
        }
        return true;
    }

    public void runEnd(MapleCharacter chr, Integer extSelection) {
        switch (type) {
            case exp: {
                chr.gainExp(intStore * GameConstants.getExpRate_Quest(chr.getLevel()) * (chr.getStat().questBonus) * ((chr.getTrait(MapleTraitType.sense).getLevel() * 3 / 10) + 100) / 100, true, true, true);
                break;
            }
            case item: {
                // first check for randomness in item selection
                Map<Integer, Integer> props = new HashMap<>();
                for (QuestItem item : items) {
                    if (item.prop > 0 && canGetItem(item, chr)) {
                        for (int i = 0; i < item.prop; i++) {
                            props.put(props.size(), item.itemid);
                        }
                    }
                }
                int selection = 0;
                int extNum = 0;
                if (props.size() > 0) {
                    selection = props.get(Randomizer.nextInt(props.size()));
                }
                for (QuestItem item : items) {
                    if (!canGetItem(item, chr)) {
                        continue;
                    }
                    int id = item.itemid;
                    if (item.prop != -2) {
                        if (item.prop == -1) {
                            if (extSelection != null && extSelection != extNum++) {
                                continue;
                            }
                        } else if (id != selection) {
                            continue;
                        }
                    }
                    short count = (short) item.count;
                    if (count < 0) { // 删除任务道具
                        MapleInventoryManipulator.removeById(chr.getClient(), ItemConstants.getInventoryType(id), id, (count * -1), true, false);
                        chr.send(MaplePacketCreator.getShowItemGain(id, count, true));
                    } else { // 给任务奖励道具
                        int period = item.period / 1440; //转换成天数
                        String name = MapleItemInformationProvider.getInstance().getName(id);
                        if (id / 10000 == 114 && name != null && name.length() > 0) { //如果是勋章道具奖励
                            String msg = "你获得了勋章 <" + name + ">";
                            chr.dropMessage(-1, msg);
                            chr.dropMessage(5, msg);
                        }
                        MapleInventoryManipulator.addById(chr.getClient(), id, count, "", null, period, "任务获得 " + quest.getId() + " 时间: " + DateUtil.getCurrentDate());
                        chr.send(MaplePacketCreator.getShowItemGain(id, count, true));
                    }
                }
                break;
            }
            case nextQuest: {
                chr.send(MaplePacketCreator.updateQuestInfo(quest.getId(), chr.getQuest(quest).getNpc(), intStore, false));
                break;
            }
            case money: {
                chr.gainMeso(intStore, true, true);
                break;
            }
            case quest: {
                for (Pair<Integer, Integer> q : state) {
                    chr.updateQuest(new MapleQuestStatus(MapleQuest.getInstance(q.left), q.right));
                }
                break;
            }
            case skill:
                Map<Integer, SkillEntry> list = new HashMap<>();
                for (Triple<Integer, Integer, Integer> skills : skill) {
                    int skillid = skills.left;
                    int skillLevel = skills.mid;
                    int masterLevel = skills.right;
                    Skill skillObject = SkillFactory.getSkill(skillid);
                    boolean found = false;
                    for (int applicableJob : applicableJobs) {
                        if (chr.getJob() == applicableJob) {
                            found = true;
                            break;
                        }
                    }
                    if (skillObject.isBeginnerSkill() || found) {
                        list.put(skillid, new SkillEntry((byte) Math.max(skillLevel, chr.getSkillLevel(skillObject)), (byte) Math.max(masterLevel, chr.getMasterLevel(skillObject)), SkillFactory.getDefaultSExpiry(skillObject)));
                    }
                }
                chr.changeSkillsLevel(list);
                break;
            case pop: {
                int fameGain = intStore;
                chr.addFame(fameGain);
                chr.updateSingleStat(MapleStat.人气, chr.getFame());
                chr.send(MaplePacketCreator.getShowFameGain(fameGain));
                break;
            }
            case buffItemID: {
                int tobuff = intStore;
                if (tobuff <= 0) {
                    break;
                }
                MapleItemInformationProvider.getInstance().getItemEffect(tobuff).applyTo(chr);
                break;
            }
            case infoNumber: {
//		System.out.println("quest : "+intStore+"");
//		MapleQuest.getInstance(intStore).forceComplete(c, 0);
                break;
            }
            case sp: {
                int sp_val = intStore;
                if (applicableJobs.size() > 0) {
                    int finalJob = 0;
                    for (int job_val : applicableJobs) {
                        if (chr.getJob() >= job_val && job_val > finalJob) {
                            finalJob = job_val;
                        }
                    }
                    if (finalJob == 0) {
                        chr.gainSP(sp_val);
                    } else {
                        chr.gainSP(sp_val, JobConstants.getSkillBookByJob(finalJob));
                    }
                } else {
                    chr.gainSP(sp_val);
                }
                break;
            }
            case charmEXP:
            case charismaEXP:
            case craftEXP:
            case insightEXP:
            case senseEXP:
            case willEXP: {
                chr.getTrait(MapleTraitType.getByQuestName(type.name())).addExp(intStore, chr);
                break;
            }
            default:
                break;
        }
    }







    public MapleQuestActionType getType() {
        /* 623 */
        return this.type;

    }




    public String toString() {
        /* 628 */
        return this.type.toString();

    }



    public List<Triple<Integer, Integer, Integer>> getSkills() {
        /* 632 */
        return this.skill;

    }



    public List<QuestItem> getItems() {
        /* 636 */
        return this.items;

    }


       public static class QuestItem
             {
             public final int itemid;
             public final int count;
             public final int period;
             public final int gender;
             public final int job;
             public final int jobEx;
             public final int prop;



        public QuestItem(int itemid, int count, int period, int gender, int job, int jobEx, int prop) {
            /* 650 */
            if (RandomRewards.getTenPercent().contains(Integer.valueOf(itemid))) {
                /* 651 */
                count += Randomizer.nextInt(3);

            }
            /* 653 */
            this.itemid = itemid;
            /* 654 */
            this.count = count;
            /* 655 */
            this.period = period;
            /* 656 */
            this.gender = gender;
            /* 657 */
            this.job = job;
            /* 658 */
            this.jobEx = jobEx;
            /* 659 */
            this.prop = prop;

        }

    }

}


/* Location:              C:\PGX\Server.jar!\server\quest\MapleQuestAction.class
 * Java compiler version: 8 (52.0)
 * JD-Core Version:       1.1.3
 */